<template><div><h1 id="object-defineproperty详解" tabindex="-1"><a class="header-anchor" href="#object-defineproperty详解" aria-hidden="true">#</a> Object.defineproperty详解</h1>
<h2 id="一、参数介绍" tabindex="-1"><a class="header-anchor" href="#一、参数介绍" aria-hidden="true">#</a> 一、参数介绍</h2>
<h3 id="_1、这个方法接收三个参数" tabindex="-1"><a class="header-anchor" href="#_1、这个方法接收三个参数" aria-hidden="true">#</a> 1、这个方法接收三个参数：</h3>
<ul>
<li>属性所在的对象</li>
<li>属性的名字</li>
<li>一个描述符对象</li>
</ul>
<h3 id="_2、描述符对象" tabindex="-1"><a class="header-anchor" href="#_2、描述符对象" aria-hidden="true">#</a> 2、描述符对象</h3>
<blockquote>
<p>他可以是 数据属性，也可以是访问器属性</p>
</blockquote>
<table>
<thead>
<tr>
<th>参数</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>configurable</td>
<td>表示能否通过delete删除属性从而重新定义属性，能否修改属性的特性，或者能否把属性修改为访问器属性，默认值为false</td>
</tr>
<tr>
<td>enumerable</td>
<td>表示能否通过for in循环访问属性，默认值为false</td>
</tr>
<tr>
<td>writable</td>
<td>表示能否修改属性的值。默认值为false</td>
</tr>
<tr>
<td>value</td>
<td>包含这个属性的数据值。默认值为undefined</td>
</tr>
</tbody>
</table>
<div class="custom-container tip">
<p class="custom-container-title">提示</p>
<p><code v-pre>configurable</code>若为true，<code v-pre>writable</code>为false,则value不可修改;<br>
<code v-pre>configurable</code>若为false，<code v-pre>writable</code>为true,则value可修改;</p>
</div>
<h2 id="二、示例" tabindex="-1"><a class="header-anchor" href="#二、示例" aria-hidden="true">#</a> 二、示例</h2>
<div class="language-javascript ext-js line-numbers-mode"><pre v-pre class="language-javascript"><code><span class="token comment">// 公共对象 </span>
<span class="token keyword">var</span> p1 <span class="token operator">=</span><span class="token punctuation">{</span>
    <span class="token literal-property property">name</span><span class="token operator">:</span><span class="token string">"lisi"</span><span class="token punctuation">,</span>
    <span class="token literal-property property">age</span><span class="token operator">:</span><span class="token string">'22'</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="_1-configurable" tabindex="-1"><a class="header-anchor" href="#_1-configurable" aria-hidden="true">#</a> 1.configurable</h3>
<blockquote>
<p>configurable 为真，writable 为假,直接给属性无法赋值，但是可以通过重新定义的方式进行赋值,并且可以删除属性</p>
</blockquote>
<div class="language-javascript ext-js line-numbers-mode"><pre v-pre class="language-javascript"><code><span class="token comment">// 通过这个方法设置好configurable 这个属性，delete就不能把name属性给删除掉了</span>
Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>p1<span class="token punctuation">,</span><span class="token string">"name"</span><span class="token punctuation">,</span><span class="token punctuation">{</span>
    <span class="token literal-property property">configurable</span> <span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>   <span class="token comment">// 不可修改</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//{ name: 'lisi',age:'22' }</span>
<span class="token keyword">delete</span> p1<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//{ name: 'lisi',age:'22'}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="language-javascript ext-js line-numbers-mode"><pre v-pre class="language-javascript"><code>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>p1<span class="token punctuation">,</span><span class="token string">"name"</span><span class="token punctuation">,</span><span class="token punctuation">{</span>
    <span class="token literal-property property">configurable</span> <span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>   <span class="token comment">// 可以修改</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//{ name: 'lisi',age:'22' }</span>
<span class="token keyword">delete</span> p1<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//{ age:'22'}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="_2-writable" tabindex="-1"><a class="header-anchor" href="#_2-writable" aria-hidden="true">#</a> 2.writable</h3>
<div class="language-javascript ext-js line-numbers-mode"><pre v-pre class="language-javascript"><code><span class="token comment">//然后我们给p1这个对象新加了一个age属性，并且设置成只读的。</span>
<span class="token comment">//这样我们就无法修改这个age属性了。</span>
Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>p1<span class="token punctuation">,</span> <span class="token string">'sex'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">writable</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
  <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token string">'男'</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'p1==='</span><span class="token punctuation">,</span> p1<span class="token punctuation">.</span>sex<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// 男</span>
p1<span class="token punctuation">.</span>sex <span class="token operator">=</span> <span class="token string">'女'</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'p1==='</span><span class="token punctuation">,</span> p1<span class="token punctuation">.</span>sex<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// 男</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="language-javascript ext-js line-numbers-mode"><pre v-pre class="language-javascript"><code>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>p1<span class="token punctuation">,</span> <span class="token string">'sex'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">writable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
  <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token string">'男'</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'p1==='</span><span class="token punctuation">,</span> p1<span class="token punctuation">.</span>sex<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// 男</span>
p1<span class="token punctuation">.</span>sex <span class="token operator">=</span> <span class="token string">'女'</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'p1==='</span><span class="token punctuation">,</span> p1<span class="token punctuation">.</span>sex<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// 女</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="_3-enumerable" tabindex="-1"><a class="header-anchor" href="#_3-enumerable" aria-hidden="true">#</a> 3.enumerable</h3>
<div class="language-javascript ext-js line-numbers-mode"><pre v-pre class="language-javascript"><code><span class="token comment">// 在通过这个方法给enumerable设置为false，这样对象就不能通过迭代器遍历出sex这个属性的值了。</span>
Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>p1<span class="token punctuation">,</span><span class="token string">"sex"</span><span class="token punctuation">,</span><span class="token punctuation">{</span>
    <span class="token literal-property property">enumerable</span><span class="token operator">:</span><span class="token boolean">false</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token keyword">in</span> p1<span class="token punctuation">)</span><span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token comment">// lisi  22</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="language-javascript ext-js line-numbers-mode"><pre v-pre class="language-javascript"><code>Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>p1<span class="token punctuation">,</span><span class="token string">"sex"</span><span class="token punctuation">,</span><span class="token punctuation">{</span>
    <span class="token literal-property property">enumerable</span><span class="token operator">:</span><span class="token boolean">true</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token keyword">in</span> p1<span class="token punctuation">)</span><span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token comment">// lisi  22 undefined</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="三、访问器属性" tabindex="-1"><a class="header-anchor" href="#三、访问器属性" aria-hidden="true">#</a> 三、访问器属性</h2>
<ul>
<li>get：在读取属性时调用的函数，默认值是undefined</li>
<li>set：在写入属性的时候调用的函数，默认值是undefined</li>
</ul>
<p><strong>示例</strong></p>
<div class="language-javascript ext-js line-numbers-mode"><pre v-pre class="language-javascript"><code><span class="token comment">//由于get方法返回_year的值，set方法通过计算来确定正确的版本。</span>
<span class="token comment">//因此把year的值设置为2005会导致edition的值变为2.</span>
<span class="token keyword">var</span> book <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">_year</span><span class="token operator">:</span> <span class="token number">2004</span><span class="token punctuation">,</span>
  <span class="token literal-property property">edition</span><span class="token operator">:</span> <span class="token number">1</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>book<span class="token punctuation">,</span> <span class="token string">'year'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
  <span class="token function-variable function">get</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_year<span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token function-variable function">set</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">newYear</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>newYear <span class="token operator">></span> <span class="token number">2004</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>_year <span class="token operator">=</span> newYear<span class="token punctuation">;</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>edition <span class="token operator">+=</span> newYear <span class="token operator">-</span> <span class="token number">2004</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>book<span class="token punctuation">.</span>year<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//2004</span>
book<span class="token punctuation">.</span>year <span class="token operator">=</span> <span class="token number">2005</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>book<span class="token punctuation">.</span>edition<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>book<span class="token punctuation">.</span>_year<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//2005</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="四、定义多属性" tabindex="-1"><a class="header-anchor" href="#四、定义多属性" aria-hidden="true">#</a> 四、定义多属性</h2>
<blockquote>
<p>vue源码中一般采用递归的方法</p>
</blockquote>
<div class="language-javascript ext-js line-numbers-mode"><pre v-pre class="language-javascript"><code><span class="token keyword">var</span> student <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
Object<span class="token punctuation">.</span><span class="token function">defineProperties</span><span class="token punctuation">(</span>student<span class="token punctuation">,</span><span class="token punctuation">{</span>
    <span class="token literal-property property">name</span><span class="token operator">:</span><span class="token punctuation">{</span>
        <span class="token literal-property property">writable</span><span class="token operator">:</span><span class="token boolean">false</span><span class="token punctuation">,</span>
        <span class="token literal-property property">value</span><span class="token operator">:</span><span class="token string">"lisi"</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token literal-property property">age</span> <span class="token operator">:</span> <span class="token punctuation">{</span>
        <span class="token literal-property property">writable</span><span class="token operator">:</span><span class="token boolean">true</span><span class="token punctuation">,</span>
        <span class="token literal-property property">value</span> <span class="token operator">:</span> <span class="token number">16</span><span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token literal-property property">sex</span><span class="token operator">:</span><span class="token punctuation">{</span>
        <span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token string">'男'</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token function">set</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span><span class="token punctuation">{</span>
            p1<span class="token punctuation">.</span>sex <span class="token operator">=</span> v
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

p1<span class="token punctuation">.</span>sex <span class="token operator">=</span> <span class="token string">"男"</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>student<span class="token punctuation">.</span>name <span class="token operator">+</span> <span class="token string">":"</span> <span class="token operator">+</span> student<span class="token punctuation">.</span>age<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p1<span class="token punctuation">.</span>sex<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 男</span>
student<span class="token punctuation">.</span>sex <span class="token operator">=</span> <span class="token string">"女"</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>student<span class="token punctuation">.</span>sex<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//男</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>p1<span class="token punctuation">.</span>sex<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 女</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></div></template>


